Add FUSE 3 support
authorHilko Bengen <bengen@debian.org>
Mon, 29 Dec 2025 00:27:29 +0000 (01:27 +0100)
committerHilko Bengen <bengen@debian.org>
Sun, 8 Feb 2026 12:36:00 +0000 (13:36 +0100)
Gbp-Pq: Name Add-FUSE-3-support.patch

fuse/guestmount.c
lib/fuse.c
m4/guestfs-fuse.m4

index 6ea07edf4278a6b7954333a7b1e5e55a1e44180a..488d1da88841584be4beeb445754bf854da9671b 100644 (file)
@@ -16,8 +16,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#define FUSE_USE_VERSION 26
-
 #include <config.h>
 
 #include <stdio.h>
index aaf740a969a54bc799fdd1162d62ee09e6a51f9f..ee8709d552ba3f4025707421577137270beaf80b 100644 (file)
@@ -40,8 +40,6 @@
 #define ENOATTR ENODATA
 #endif
 
-#define FUSE_USE_VERSION 26
-
 #include <fuse.h>
 #include <fuse_lowlevel.h>
 #endif
@@ -113,9 +111,15 @@ copy_xattr_list (guestfs_h *g, const struct guestfs_xattr *first, size_t num)
   return xattrs;
 }
 
+#if FUSE_USE_VERSION < 30
 static int
 mount_local_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
                      off_t offset, struct fuse_file_info *fi)
+#else
+static int
+mount_local_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
+                     off_t offset, struct fuse_file_info *fi, enum fuse_readdir_flags)
+#endif
 {
   time_t now;
   size_t i;
@@ -154,8 +158,13 @@ mount_local_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
      * not quite sure how this is ever supposed to work on large
      * directories. XXX
      */
+#if FUSE_USE_VERSION < 30
     if (filler (buf, ents->val[i].name, &stat, 0))
       break;
+#else
+    if (filler (buf, ents->val[i].name, &stat, 0, 0))
+      break;
+#endif
   }
 
   /* Now prepopulate the directory caches.  This step is just an
@@ -249,8 +258,13 @@ mount_local_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
   return 0;
 }
 
+#if FUSE_USE_VERSION < 30
 static int
 mount_local_getattr (const char *path, struct stat *statbuf)
+#else
+static int
+mount_local_getattr (const char *path, struct stat *statbuf, struct fuse_file_info*)
+#endif
 {
   const struct stat *buf;
   CLEANUP_FREE_STAT struct guestfs_statns *r = NULL;
@@ -311,7 +325,7 @@ mount_local_access (const char *path, int mask)
   if (g->ml_read_only && (mask & W_OK))
     return -EROFS;
 
-  r = mount_local_getattr (path, &statbuf);
+  r = mount_local_getattr (path, &statbuf, NULL);
   if (r < 0 || mask == F_OK) {
     debug (g, "%s: mount_local_getattr returned r = %d", path, r);
     return r;
@@ -489,8 +503,13 @@ mount_local_symlink (const char *from, const char *to)
   return 0;
 }
 
+#if FUSE_USE_VERSION < 30
 static int
 mount_local_rename (const char *from, const char *to)
+#else
+static int
+mount_local_rename (const char *from, const char *to, unsigned int)
+#endif  
 {
   int r;
   DECL_G ();
@@ -527,8 +546,13 @@ mount_local_link (const char *from, const char *to)
   return 0;
 }
 
+#if FUSE_USE_VERSION < 30
 static int
 mount_local_chmod (const char *path, mode_t mode)
+#else
+static int
+mount_local_chmod (const char *path, mode_t mode, struct fuse_file_info*)
+#endif
 {
   int r;
   DECL_G ();
@@ -545,8 +569,13 @@ mount_local_chmod (const char *path, mode_t mode)
   return 0;
 }
 
+#if FUSE_USE_VERSION < 30
 static int
 mount_local_chown (const char *path, uid_t uid, gid_t gid)
+#else
+static int
+mount_local_chown (const char *path, uid_t uid, gid_t gid, struct fuse_file_info*)
+#endif
 {
   int r;
   DECL_G ();
@@ -563,8 +592,13 @@ mount_local_chown (const char *path, uid_t uid, gid_t gid)
   return 0;
 }
 
+#if FUSE_USE_VERSION < 30
 static int
 mount_local_truncate (const char *path, off_t size)
+#else
+static int
+mount_local_truncate (const char *path, off_t size, struct fuse_file_info*)
+#endif  
 {
   int r;
   DECL_G ();
@@ -581,8 +615,13 @@ mount_local_truncate (const char *path, off_t size)
   return 0;
 }
 
+#if FUSE_USE_VERSION < 30
 static int
 mount_local_utimens (const char *path, const struct timespec ts[2])
+#else
+static int
+mount_local_utimens (const char *path, const struct timespec ts[2], struct fuse_file_info*)
+#endif
 {
   int r;
   time_t atsecs, mtsecs;
@@ -960,7 +999,9 @@ guestfs_impl_mount_local (guestfs_h *g, const char *localmountpoint,
 {
   const char *t;
   struct fuse_args args = FUSE_ARGS_INIT (0, NULL);
+#if FUSE_USE_VERSION < 30
   struct fuse_chan *ch;
+#endif
   int fd;
 
   /* You can only mount each handle in one place in one thread. */
@@ -1007,6 +1048,7 @@ guestfs_impl_mount_local (guestfs_h *g, const char *localmountpoint,
 
   debug (g, "%s: fuse_mount %s", __func__, localmountpoint);
 
+#if FUSE_USE_VERSION < 30
   /* Create the FUSE mountpoint. */
   ch = fuse_mount (localmountpoint, &args);
   if (ch == NULL) {
@@ -1035,6 +1077,29 @@ guestfs_impl_mount_local (guestfs_h *g, const char *localmountpoint,
     guestfs_int_free_fuse (g);
     return -1;
   }
+#else
+  g->fuse = fuse_new (&args,
+                      &mount_local_operations, sizeof mount_local_operations,
+                      g);
+  if (!g->fuse) {
+    perrorf (g, _("fuse_new: %s"), localmountpoint);
+    fuse_opt_free_args (&args);
+    guestfs_int_free_fuse (g);
+    return -1;
+  }
+
+  if (fuse_mount (g->fuse, localmountpoint) == -1) {
+    error (g, _("fuse_mount failed: %s, see error messages above"),
+           localmountpoint);
+    fuse_opt_free_args (&args);
+    guestfs_int_free_fuse (g);
+    return -1;
+  }
+
+  fd = fuse_session_fd (fuse_get_session (g->fuse));
+  if (fd >= 0)
+    set_cloexec_flag (fd, 1);
+#endif
 
   fuse_opt_free_args (&args);
 
index 08b2bffa7739925b526a7838506d079465d38f08..f6964e7e8a45def97b6b046381027d7679f87f65 100644 (file)
@@ -21,17 +21,29 @@ AC_ARG_ENABLE([fuse],
     [],
     [enable_fuse=yes])
 AS_IF([test "x$enable_fuse" != "xno"],[
-    PKG_CHECK_MODULES([FUSE],[fuse],[
+    PKG_CHECK_MODULES([FUSE],[fuse3],[
         AC_SUBST([FUSE_CFLAGS])
         AC_SUBST([FUSE_LIBS])
         AC_DEFINE([HAVE_FUSE],[1],[Define to 1 if you have FUSE.])
+        AC_DEFINE([FUSE_USE_VERSION],[30],[Set FUSE compatibility version])
         old_LIBS="$LIBS"
         LIBS="$FUSE_LIBS $LIBS"
         AC_CHECK_FUNCS([fuse_opt_add_opt_escaped])
         LIBS="$old_LIBS"
     ],[
-        enable_fuse=no
-        AC_MSG_WARN([FUSE library and headers are missing, so optional FUSE module won't be built])
+        PKG_CHECK_MODULES([FUSE],[fuse],[
+            AC_SUBST([FUSE_CFLAGS])
+            AC_SUBST([FUSE_LIBS])
+            AC_DEFINE([HAVE_FUSE],[1],[Define to 1 if you have FUSE.])
+            AC_DEFINE([FUSE_USE_VERSION],[26],[Set FUSE compatibility version])
+            old_LIBS="$LIBS"
+            LIBS="$FUSE_LIBS $LIBS"
+            AC_CHECK_FUNCS([fuse_opt_add_opt_escaped])
+            LIBS="$old_LIBS"
+        ],[
+            enable_fuse=no
+            AC_MSG_WARN([FUSE library and headers are missing, so optional FUSE module won't be built])
+        ])
     ])
 ])
 AM_CONDITIONAL([HAVE_FUSE],[test "x$enable_fuse" != "xno"])